﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ClientLib;
using ServerLibForClient;
using System.Threading;
using System.Runtime.Remoting.Channels.Tcp;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting;
using System.Security.Permissions;

namespace Client
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// Флаг инициализации сервера ремоутинга
        /// </summary>
        bool isRemoutingInit = false;

        /// <summary>
        /// Хранилище результатов поиска
        /// </summary>
        System.Collections.ObjectModel.ObservableCollection<ResultStruct> ResultDataSource = new System.Collections.ObjectModel.ObservableCollection<ResultStruct>();

        public MainWindow()
        {
            InitializeComponent();
            ResultFunctions.ResultEvent += new ResultFunctions.ResultEventHandler(ResultFunctions_ResultEvent);
            dataGrid1.ItemsSource = ResultDataSource;
        }

        private void CreateTaskSearch(string serverHost, string serverPort, string serchData, string clientHost, string clientPort)
        {
            SearchRequest SearchRequestProxy = (SearchRequest)Activator.GetObject(typeof(SearchRequest), serverHost + ":" + serverPort + "/SearchRequest.soap");
            SearchRequestStruct SearchRequestData = new SearchRequestStruct(serchData, clientHost, clientPort);

            SendTaskOnServer(SearchRequestProxy, SearchRequestData);
        }

        private void SendTaskOnServer(SearchRequest SearchRequestProxy, SearchRequestStruct SearchRequestData)
        {
            SearchRequestProxy.BeginSerch(SearchRequestData);
        }

        private void RequestResult(string serverHost, string serverPort, string serchData, string clientHost, string clientPort)
        {
            SearchRequest SearchRequestProxy = (SearchRequest)Activator.GetObject(typeof(SearchRequest), serverHost + ":" + serverPort + "/SearchRequest.soap");
            SearchRequestStruct SearchRequestData = new SearchRequestStruct(serchData, clientHost, clientPort);

            SearchRequestProxy.GetResults(SearchRequestData);
        }

        private void Clean()
        {
            ResultDataSource.Clear();
        }

        private void buttonSearch_Click(object sender, RoutedEventArgs e)
        {
            // Проверка инициализации ремоутинга
            if (!initRemouting())
                return;

            try
            {
                string serverHost = textBoxServerHost.Text;
                string serverPort = textBoxServerPort.Text;

                string serchData = textBox1.Text;
                string clientHost = textBoxClientHost.Text;
                string clientPort = textBoxClientPort.Text;

                CreateTaskSearch(serverHost, serverPort, serchData, clientHost, clientPort);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("buttonSearch_Click " + ex.Message);
            }
        }

        private void buttonGetResults_Click(object sender, RoutedEventArgs e)
        {
            // Проверка инициализации ремоутинга
            if (!initRemouting())
                return;

            try
            {
                string serverHost = textBoxServerHost.Text;
                string serverPort = textBoxServerPort.Text;

                string serchData = textBox1.Text;
                string clientHost = textBoxClientHost.Text;
                string clientPort = textBoxClientPort.Text;

                RequestResult(serverHost, serverPort, serchData, clientHost, clientPort);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        /// <summary>
        /// Эвент, вызываемый тогда, когда пришел результат поиска
        /// </summary>
        /// <param name="resStruct">Данные результата поиска</param>
        void ResultFunctions_ResultEvent(ResultStruct resStruct)
        {
            try
            {
                // Добавление данных в базу
                Application.Current.Dispatcher.Invoke((ThreadStart)delegate { ResultDataSource.Add(resStruct); });
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("ResultFunctions_ResultEvent " + ex.Message);
            }
        }

        /// <summary>
        /// Инициализация сервера ремоутинга
        /// </summary>
        /// <returns>Результат инициализации</returns>
        bool initRemouting()
        {
            if (!isRemoutingInit)
            {
                try
                {
                    string port = textBoxClientPort.Text;

                    BinaryServerFormatterSinkProvider binaryServerFormatterSinkProvider = new BinaryServerFormatterSinkProvider();
                    binaryServerFormatterSinkProvider.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full;

                    TcpServerChannel server_channel = new TcpServerChannel("ResultChanel", Int32.Parse(port), binaryServerFormatterSinkProvider);
                    ChannelServices.RegisterChannel(server_channel, false);

                    //RemotingConfiguration.RegisterWellKnownServiceType(typeof(ClientLib.ResultFunctions), "ResultFunctions.soap", WellKnownObjectMode.SingleCall);
                    RemotingConfiguration.RegisterWellKnownServiceType(typeof(ClientLib.ResultFunctions), "ResultFunctions.soap", WellKnownObjectMode.Singleton);
                    isRemoutingInit = true;
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("initRemouting " + ex.Message);
                    isRemoutingInit = false;
                }
            }
            return isRemoutingInit;
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Clean();
        }
    }
}
